package com.kakarote.oa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Tuple;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.TypeUtils;
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kakarote.common.field.utils.FieldUtil;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.enums.BehaviorEnum;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.enums.CrmRelationTypeEnum;
import com.kakarote.core.common.enums.FieldEnum;
import com.kakarote.core.common.enums.LanguageFieldEnum;
import com.kakarote.core.common.enums.SystemCodeEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.entity.CrmRelationDTO;
import com.kakarote.core.entity.PageEntity;
import com.kakarote.core.entity.UserInfo;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.admin.entity.*;
import com.kakarote.core.feign.admin.service.AdminFileService;
import com.kakarote.core.feign.admin.service.AdminMessageService;
import com.kakarote.core.feign.crm.entity.ActivityContent;
import com.kakarote.core.feign.crm.entity.CrmActivityBO;
import com.kakarote.core.feign.examine.entity.*;
import com.kakarote.core.feign.examine.service.ExamineService;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.*;
import com.kakarote.oa.common.*;
import com.kakarote.oa.entity.BO.AuditExamineBO;
import com.kakarote.oa.entity.BO.ExamineExportBO;
import com.kakarote.oa.entity.BO.ExaminePageBO;
import com.kakarote.oa.entity.BO.GetExamineFieldBO;
import com.kakarote.oa.entity.PO.*;
import com.kakarote.oa.entity.VO.ExamineVO;
import com.kakarote.oa.entity.VO.OaExamineVO;
import com.kakarote.oa.entity.VO.OaLogTemplateFieldVO;
import com.kakarote.oa.mapper.OaExamineLogMapper;
import com.kakarote.oa.mapper.OaExamineMapper;
import com.kakarote.oa.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.kakarote.core.servlet.ApplicationContextHolder.getBean;

/**
 * <p>
 * 审批表 服务实现类
 * </p>
 *
 * @author wyq
 * @since 2020-05-15
 */
@Service
public class OaExamineServiceImpl extends BaseServiceImpl<OaExamineMapper, OaExamine> implements IOaExamineService {

    @Autowired
    private IOaExamineFieldExtendService oaExamineFieldExtendService;


    @Autowired
    private OaExamineMapper examineMapper;

    @Autowired
    private IOaExamineRelationService examineRelationService;

    @Autowired
    private AdminFileService adminFileService;

    @Autowired
    private IOaExamineTravelService examineTravelService;

    @Autowired
    private OaExamineLogMapper examineLogMapper;

    @Autowired
    private IOaExamineCategoryService examineCategoryService;

    @Autowired
    private IOaExamineFieldService examineFieldService;

    @Autowired
    private IOaExamineDataService examineDataService;

    @Autowired
    private IOaExamineStepService examineStepService;

    @Autowired
    private IOaExamineRecordService examineRecordService;

    @Autowired
    private IOaExamineLogService examineLogService;

    @Autowired
    private IOaExamineService oaExamineService;

    @Autowired
    private ExamineService examineService;

    @Autowired
    private IOaLogTemplateConfigService oaLogTemplateConfigService;

    @Autowired
    private IOaLogPrintTemplateService oaLogPrintTemplateService;

    @Autowired
    private IOaLogTemplateFieldService oaLogTemplateFieldService;

    @Autowired
    private OaExaminePrintTemplateServiceImpl oaExaminePrintTemplateService;

    @Autowired
    private IOaExamineFieldService oaExamineFieldService;

    private static final int FOUR = 4;

    private static final int TWO = 2;

    private static final int THREE = 3;

    private static final String IMG = "img";

    private static final String FILE = "file";

    private static final String STEP_TYPE = "stepType";

    private static final String CONTENT = "content";

    private static final String REMARK = "remark";

    private static final String EXAMINE_STATUS = "examineStatus";

    @Override
    public BasePage<ExamineVO> myInitiate(ExaminePageBO examinePageBO) {
        if (examinePageBO.getCategoryId() != null) {
            ExamineInfoVo infoVo = examineService.queryExamineById(examinePageBO.getCategoryId()).getData();
            examinePageBO.setCategoryId(infoVo != null ? infoVo.getExamineInitId() : null);
        }
        BasePage<ExamineVO> page = examineMapper.myInitiateOaExamine(examinePageBO.parse().setOptimizeCountSql(false), examinePageBO, UserUtil.getUserId(), UserUtil.isAdmin());
        transfer(page.getList());
        return page;
    }

    @Override
    public BasePage<ExamineVO> myOaExamine(ExaminePageBO examinePageBO) {
        BasePage<ExamineVO> page = examineMapper.myOaExamine(examinePageBO.parse(), examinePageBO, UserUtil.getUserId(), UserUtil.isAdmin());
        transfer(page.getList());
        return page;
    }

    @Override
    public List<ExamineVO> transfer(List<ExamineVO> recordList) {
        //------------------------------------------------
        //补全自定义基础字段信息
        List<String> oaExamineBatchList = recordList.stream().map(OaExamine::getBatchId).collect(Collectors.toList());
        List<OaExamineData> oaExamineDataList = examineDataService.lambdaQuery().in(OaExamineData::getBatchId, oaExamineBatchList).list();
        //------------------------------------------------
        Long userId = UserUtil.getUserId();
        recordList.forEach(record -> {
            setRelation(record);
            //获取创建人信息
            SimpleUser listResult = UserCacheUtil.getSimpleUser(record.getCreateUserId());
            record.setCreateUser(listResult);
            //获取上一步处理人信息
            SimpleUser lastHandleUser = UserCacheUtil.getSimpleUser(record.getLastHandleUserId());
            record.setLastHandleUser(lastHandleUser);
            String batchId = record.getBatchId();
            ExamineRecordReturnVO recordReturnVO;
            if (record.getExamineRecordId() != null) {
                recordReturnVO = examineService.queryExamineRecordInfo(record.getExamineRecordId()).getData();
            } else {
                recordReturnVO = new ExamineRecordReturnVO();
                recordReturnVO.setExamineStatus(1);
                recordReturnVO.setExamineUserIds(new ArrayList<>());
            }

            Integer examineStatus = recordReturnVO.getExamineStatus();
            if (examineStatus == null) {
                examineStatus = -1;
            }
            record.setExamineStatus(examineStatus);
            List<Long> userIds = recordReturnVO.getExamineUserIds();
            String examineName = "";
            if (CollUtil.isNotEmpty(userIds) && examineStatus != FOUR) {
                List<SimpleUser> userList = UserCacheUtil.getSimpleUsers(userIds);
                examineName = userList.stream().map(SimpleUser::getRealname).collect(Collectors.joining(","));
            }
            if (examineStatus == FOUR) {
                examineName = record.getCreateUser().getRealname();
            }

            record.setExamineName(examineName);
            ExamineInfoVo examineInfoVo = examineService.queryExamineById(record.getCategoryId()).getData();
            String title = "";
            if (examineInfoVo != null) {
                title = examineInfoVo.getExamineName();
                record.setExamineIcon(examineInfoVo.getExamineIcon());
                record.setType(examineInfoVo.getOaType());
            }
            record.setCategoryTitle(title);
            Result<List<FileEntity>> fileList = adminFileService.queryFileList(batchId);
            Map<String, List<FileEntity>> collect = fileList.getData().stream().collect(Collectors.groupingBy(FileEntity::getFileType));
            if (collect.containsKey(IMG)) {
                record.setImg(collect.get("img"));
            } else {
                record.setImg(new ArrayList<>());
            }
            if (collect.containsKey(FILE)) {
                record.setFile(collect.get("file"));
            } else {
                record.setFile(new ArrayList<>());
            }
            setCountRecord(record);
            List<Long> roles = UserUtil.getUser().getRoles();
            Map<String, Integer> permission = new HashMap<>();
            Long createUserId = record.getCreateUserId();
            boolean examineFlagFlag = createUserId.equals(userId) && ExamineFlagEnum.DRAFT.getType().equals(record.getExamineFlag());
            //超级管理员、创建人可以更新 2审核拒绝 4 已撤回 的审批
            boolean isUpdate = false;
            if (ObjectUtil.isNotEmpty(userId)) {
                isUpdate = (userId.equals(UserUtil.getSuperUser()) || createUserId.equals(userId) || roles.contains(UserUtil.getSuperRole())) && (examineStatus == 4 || examineStatus == 2);
            }

            if (isUpdate || examineFlagFlag) {
                permission.put("isUpdate", 1);
            } else {
                permission.put("isUpdate", 0);
            }

            //超级管理员可以删除1审核通过 2审核拒绝 4已撤回 的审批，创建人可以删除4 已撤回 的审批,超级管理员可以删除 终止、作废、归档的审批
            boolean isSuperDelete = false;
            if (ObjectUtil.isNotEmpty(userId)) {
                isSuperDelete = (userId.equals(UserUtil.getSuperUser()) || roles.contains(UserUtil.getSuperRole())) && ((examineStatus == 1 || examineStatus == 2 || examineStatus == 4 || examineStatus == 13) || ExamineFlagEnum.END.getType().equals(record.getExamineFlag()) || ExamineFlagEnum.VOID.getType().equals(record.getExamineFlag()));
            }
            boolean isCreateDelete = createUserId.equals(userId) && (examineStatus == 4 || examineStatus == 13);
            if (isSuperDelete || isCreateDelete || examineFlagFlag) {
                permission.put("isDelete", 1);
            } else {
                permission.put("isDelete", 0);
            }
            //创建人可以撤回 0未审核 4审核中 的审批
            boolean isRecheck = createUserId.equals(userId) && (examineStatus == 0 || examineStatus == 3);
            if (isRecheck) {
                permission.put("isRecheck", 1);
            } else {
                permission.put("isRecheck", 0);
            }
            if (record.getExamineStatus() == TWO) {
                //如果审批删除,直接审核0
                permission.put("isCheck", 0);
            } else {
                if (examineStatus == THREE && CollUtil.isNotEmpty(userIds) && userIds.contains(userId)) {
                    permission.put("isCheck", 1);
                } else {
                    permission.put("isCheck", 0);
                }
            }
            record.setPermission(permission);
            //----------------------------------------
            if (ObjectUtil.isNotEmpty(record.getSubmitDeptId())) {
                String deptName = UserCacheUtil.getDeptName(record.getSubmitDeptId());
                if (ObjectUtil.isNotEmpty(deptName)) {
                    record.setSubmitDeptName(deptName);
                }
            }
            //----------------------------------------
        });
        return recordList;
    }

    private void setRelation(ExamineVO relationRecord) {
        // 查询并分组
        List<OaExamineRelation> oaExamineRelations = examineRelationService.lambdaQuery()
                .select(OaExamineRelation::getRelationId, OaExamineRelation::getType)
                .eq(OaExamineRelation::getExamineId, relationRecord.getExamineId())
                .list();
        // 关系ids map
        Map<Integer, Set<Long>> relationIdsMap = new HashMap<>(4);
        // 遍历添加
        oaExamineRelations.forEach(r -> {
            Set<Long> relationIds = relationIdsMap.computeIfAbsent(r.getType(), k -> new HashSet<>(oaExamineRelations.size()));
            relationIds.add(r.getRelationId());
        });
        if (CollUtil.isNotEmpty(relationIdsMap)) {
            // 查询关系数据
            CrmRelationDTO crmRelationDTO = CrmRelationUtils.getCrmRelation(relationIdsMap, relationRecord.getExamineId());
            // 设置关系数据
            relationRecord.setCustomerList(crmRelationDTO.getCustomerList());
            relationRecord.setContactsList(crmRelationDTO.getContactsList());
            relationRecord.setBusinessList(crmRelationDTO.getBusinessList());
            relationRecord.setContractList(crmRelationDTO.getContractList());
        }
    }

    private void setCountRecord(ExamineVO record) {
        Long examineId = record.getExamineId();
        String categoryTitle = record.getCategoryTitle();
        Long count = examineTravelService.lambdaQuery().eq(OaExamineTravel::getExamineId, examineId).count();
        StringBuilder causeTitle = new StringBuilder();
        if (count > 0L) {
            causeTitle.append(count);
            switch (categoryTitle) {
                case "出差审批":
                    causeTitle.append("个行程，共");
                    if (record.getDuration() != null) {
                        causeTitle.append(record.getDuration());
                    } else {
                        causeTitle.append(0);
                    }
                    causeTitle.append("天。");
                    break;
                case "差旅报销":
                    causeTitle.append("个报销事项，共");
                    if (record.getMoney() != null) {
                        causeTitle.append(record.getMoney());
                    } else {
                        causeTitle.append(0);
                    }
                    causeTitle.append("元。");
                    break;
                default:
                    break;
            }
        }
        record.setCauseTitle(causeTitle.toString());
    }

    @Override
    public List<OaExamineField> getField(GetExamineFieldBO getExamineFieldBO) {
        OaExamine oaExamineInfo = getById(getExamineFieldBO.getExamineId());
        Long categoryId = oaExamineInfo.getCategoryId();
        ExamineInfoVo examineInfoVo = examineService.queryExamineById(categoryId).getData();
        List<OaExamineTravel> examineTravelList = examineTravelService.lambdaQuery().eq(OaExamineTravel::getExamineId, oaExamineInfo.getExamineId()).list();

        examineTravelList.forEach(record -> {
            if (StrUtil.isNotEmpty(record.getBatchId())) {
                Result<List<FileEntity>> fileList = adminFileService.queryFileList(record.getBatchId());
                Map<String, List<FileEntity>> listMap = fileList.getData().stream().collect(Collectors.groupingBy(FileEntity::getFileType));
                if (listMap.containsKey(IMG)) {
                    record.setImg(listMap.get("img"));
                } else {
                    record.setImg(new ArrayList<>());
                }
                if (listMap.containsKey(FILE)) {
                    record.setFile(listMap.get("file"));
                } else {
                    record.setFile(new ArrayList<>());
                }
            }
        });
        List<String> arr = new ArrayList<>();
        Integer oaType = Optional.ofNullable(examineInfoVo.getOaType()).orElse(0);
        List<OaExamineField> fieldList = new ArrayList<>();
        switch (oaType) {
            case 1:
                fieldList.add(OaExamineField.of(1L, "content", "审批内容", "text", arr, 1, 0, oaExamineInfo.getContent(), "", 3, 1, "0,0", 0));
                fieldList.add(OaExamineField.of(2L, "remark", "备注", "textarea", arr, 0, 0, oaExamineInfo.getRemark(), "", 3, 1, "1,0", 1));
                break;
            case 2:
                fieldList.add(OaExamineField.of(3L, "type_id", "请假类型", "select", Arrays.asList("年假", "事假", "病假", "产假", "调休", "婚假", "丧假", "其他"), 1, 0, oaExamineInfo.getTypeId(), "", 3, 1, "0,0", 1));
                fieldList.add(OaExamineField.of(4L, "content", "请假事由", "text", arr, 1, 0, oaExamineInfo.getContent(), "", 3, 1, "1,0", 2));
                fieldList.add(OaExamineField.of(5L, "start_time", "开始时间", "datetime", arr, 1, 0, oaExamineInfo.getStartTime(), "", 3, 1, "2,0", 3));
                fieldList.add(OaExamineField.of(6L, "end_time", "结束时间", "datetime", arr, 1, 0, oaExamineInfo.getEndTime(), "", 3, 1, "2,1", 4));
                fieldList.add(OaExamineField.of(7L, "duration", "时长(天)", "floatnumber", arr, 1, 0, String.valueOf(oaExamineInfo.getDuration()), "", 3, 1, "3,0", 5));
                fieldList.add(OaExamineField.of(8L, "remark", "备注", "textarea", arr, 0, 0, oaExamineInfo.getRemark(), "", 3, 1, "4,0", 6));
                break;
            case 3:
                fieldList.add(OaExamineField.of(9L, "content", "出差事由", "text", arr, 1, 0, oaExamineInfo.getContent(), "", 3, 1, "0,0", 0));
                fieldList.add(OaExamineField.of(10L, "remark", "备注", "textarea", arr, 0, 0, oaExamineInfo.getRemark(), "", 3, 1, "1,0", 1));
                fieldList.add(OaExamineField.of(11L, "cause", "行程明细", "business_cause", arr, 1, 0, examineTravelList, "", 3, 1, "2,0", 2));
                fieldList.add(OaExamineField.of(12L, "duration", "出差总天数", "floatnumber", arr, 1, 0, String.valueOf(oaExamineInfo.getDuration()), "", 3, 1, "3,0", 3));
                break;
            case 4:
                fieldList.add(OaExamineField.of(13L, "content", "加班原因", "text", arr, 1, 0, oaExamineInfo.getContent(), "", 3, 1, "0,0", 0));
                fieldList.add(OaExamineField.of(14L, "start_time", "开始时间", "datetime", arr, 1, 0, oaExamineInfo.getStartTime(), "", 3, 1, "1,0", 1));
                fieldList.add(OaExamineField.of(15L, "end_time", "结束时间", "datetime", arr, 1, 0, oaExamineInfo.getEndTime(), "", 3, 1, "1,1", 2));
                fieldList.add(OaExamineField.of(16L, "duration", "加班总天数", "floatnumber", arr, 1, 0, oaExamineInfo.getDuration(), "", 3, 1, "2,0", 2));
                fieldList.add(OaExamineField.of(17L, "remark", "备注", "textarea", arr, 0, 0, oaExamineInfo.getRemark(), "", 3, 1, "3,0", 3));
                break;
            case 5:
                fieldList.add(OaExamineField.of(18L, "content", "差旅事由", "text", arr, 1, 0, oaExamineInfo.getContent(), "", 3, 1, "0,0", 0));
                fieldList.add(OaExamineField.of(19L, "cause", "费用明细", "examine_cause", arr, 1, 0, examineTravelList, "", 3, 1, "1,0", 1));
                fieldList.add(OaExamineField.of(20L, "money", "报销总金额", "floatnumber", arr, 1, 0, String.valueOf(oaExamineInfo.getMoney()), "", 3, 1, "2,0", 2));
                fieldList.add(OaExamineField.of(21L, "remark", "备注", "textarea", arr, 0, 0, oaExamineInfo.getRemark(), "", 3, 1, "3,0", 3));
                break;
            case 6:
                fieldList.add(OaExamineField.of(22L, "content", "借款事由", "text", arr, 1, 0, oaExamineInfo.getContent(), "", 3, 1, "0,0", 0));
                OaExamineField oaExamineField = OaExamineField.of(null, "money", "借款金额（元）", "floatnumber", arr, 1, 0, String.valueOf(oaExamineInfo.getMoney()), "", 3, 1, "1,0", 1);
                oaExamineField.setPrecisions(0);
                fieldList.add(oaExamineField);
                fieldList.add(OaExamineField.of(23L, "remark", "备注", "textarea", arr, 0, 0, oaExamineInfo.getRemark(), "", 3, 1, "2,0", 2));
                break;
            default:
                List<OaExamineField> examineFields = examineFieldService.queryField(categoryId, Boolean.FALSE);

                Map<Long, String> fieldData = examineFieldService.queryFieldData(oaExamineInfo.getBatchId());

                examineFields.forEach(field -> {
                    if ("typeId".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getTypeId());
                    } else if (CONTENT.equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getContent());
                    } else if ("enclosure".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getEnclosure());
                    } else if ("submitTarget".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getSubmitTarget());
                    } else if ("handled".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getHandled());
                    } else if ("telephone".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getTelephone());
                    } else if ("submit_dept_id".equals(field.getFieldName()) || "submitDeptId".equals(field.getFieldName())) {
                        Long submitDeptId = oaExamineInfo.getSubmitDeptId();
                        field.setValue(submitDeptId);
                    } else if ("submit_time".equals(field.getFieldName()) || "submitTime".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getSubmitTime());
                    } else if ("endTime".equals(field.getFieldName()) || "end_time".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getEndTime());
                    } else if ("startTime".equals(field.getFieldName()) || "start_time".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getStartTime());
                    } else if ("duration".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getDuration());
                    } else if ("remark".equals(field.getFieldName())) {
                        field.setValue(StrUtil.isBlank(oaExamineInfo.getRemark()) ? Optional.ofNullable(fieldData.get(field.getFieldId())).orElse("") : oaExamineInfo.getRemark());
                    } else if ("cause".equals(field.getFieldName())) {
                        field.setValue(examineTravelList);
                    } else if ("money".equals(field.getFieldName())) {
                        field.setValue(oaExamineInfo.getMoney());
                    }
                    if (ObjectUtil.isEmpty(field.getValue())) {
                        field.setValue(Optional.ofNullable(fieldData.get(field.getFieldId())).orElse(""));
                    }
                    field.setFormType(FieldEnum.parse(field.getType()).getFormType());
                });
                examineFieldService.transferFieldList(examineFields, getExamineFieldBO.getIsDetail());
                fieldList.addAll(examineFields);
                break;
        }


        List<Integer> list = CollectionUtil.newArrayList(1, 2, 3, 4, 5, 6);

        if (list.contains(oaType)) {
            if (ObjectUtil.isNotEmpty(oaExamineInfo.getHandled()) && NumberUtil.isNumber(oaExamineInfo.getHandled())) {
                SimpleUser simpleUser = UserCacheUtil.getSimpleUser(Long.parseLong(oaExamineInfo.getHandled()));
                fieldList.add(OaExamineField.of(24L, "handled", "经办人", FieldEnum.USER.getFormType(), arr, 0, 0, simpleUser, "", 3, 1, "3,0", 3));
            }
            if (ObjectUtil.isNotEmpty(oaExamineInfo.getSubmitDeptId())) {
                SimpleDept simpleDept = UserCacheUtil.getDeptInfo(oaExamineInfo.getSubmitDeptId());
                fieldList.add(OaExamineField.of(25L, "submitDeptId", "提交部门", FieldEnum.STRUCTURE.getFormType(), arr, 0, 0, Collections.singletonList(simpleDept), "", 3, 1, "4,0", 4));
            }
            fieldList.add(OaExamineField.of(26L, "telephone", "联系电话", FieldEnum.MOBILE.getFormType(), arr, 0, 0, oaExamineInfo.getTelephone(), "", 3, 1, "5,0", 5));
            fieldList.add(OaExamineField.of(27L, "submitTime", "提交时间", FieldEnum.DATETIME.getFormType(), arr, 0, 0, oaExamineInfo.getSubmitTime(), "", 3, 1, "6,0", 6));
        }
        for (OaExamineField field : fieldList) {
            //添加语言包key
            field.setLanguageKeyMap(LanguageFieldUtil.getFieldNameKeyMap("name_resourceKey", "customField." + "oaExamine" + oaType + ".", field.getFieldName(), field.getSetting()));
        }

        return fieldList;
    }

    @Override
    public List<List<OaExamineField>> getFormPositionField(GetExamineFieldBO getExamineFieldBO) {
        List<OaExamineField> oaExamineFields = this.getField(getExamineFieldBO);
        return FieldUtil.convertFormPositionFieldList(oaExamineFields);
    }


    @Override
    public OperationLog setOaExamine(JSONObject jsonObject) {

        OperationLog operationLog = new OperationLog();


        OaExamine oaExamine = jsonObject.getObject("oaExamine", OaExamine.class);
        JSONArray oaExamineTravelList = jsonObject.getJSONArray("oaExamineTravelList");
        //报销总金额
        if (oaExamine.getMoney() != null && oaExamine.getMoney().doubleValue() <= 0) {
            throw new CrmException(OaCodeEnum.TOTAL_REIMBURSEMENT_ERROR);
        }
        if (oaExamine.getStartTime() != null && oaExamine.getEndTime() != null) {
            if ((oaExamine.getStartTime().compareTo(oaExamine.getEndTime())) >= 0) {
                throw new CrmException(OaCodeEnum.EXAMINE_END_TIME_IS_EARLIER_THAN_START_TIME);
            }
        }
        String batchId = StrUtil.isNotEmpty(oaExamine.getBatchId()) ? oaExamine.getBatchId() : IdUtil.simpleUUID();
        saveField(oaExamine, jsonObject.getJSONArray("field"), batchId);
        oaExamine.setBatchId(batchId);

        ExamineRecordSaveBO examineRecordSaveBO = jsonObject.getObject("examineFlowData", ExamineRecordSaveBO.class);
        Long examineId = oaExamine.getExamineId();
        if (examineId == null) {
            save(oaExamine);
            examineId = oaExamine.getExamineId();
            this.supplementFieldInfo(0, examineId, null, examineRecordSaveBO);
            examineRecordSaveBO.setCategoryId(oaExamine.getCategoryId());
            ExamineRecordReturnVO examineData = examineService.addExamineRecord(examineRecordSaveBO).getData();
            setExamineFlag(oaExamine, examineData.getExamineStatus());
            oaExamine.setExamineStatus(examineData.getExamineStatus());
            oaExamine.setExamineRecordId(Convert.toLong(examineData.getRecordId()));
            updateById(oaExamine);

            operationLog.setOperationObject(oaExamine.getContent());
            operationLog.setOperationInfo("新建审批：" + oaExamine.getContent());
            operationLog.setBehavior(BehaviorEnum.SAVE);
        } else {
            OaExamine oldOaExamine = this.getById(examineId);
            this.supplementFieldInfo(0, examineId, oldOaExamine.getExamineRecordId(), examineRecordSaveBO);
            examineRecordSaveBO.setCategoryId(oaExamine.getCategoryId());
            ExamineRecordReturnVO examineData = examineService.addExamineRecord(examineRecordSaveBO).getData();
            setExamineFlag(oaExamine, examineData.getExamineStatus());
            oaExamine.setExamineStatus(examineData.getExamineStatus());
            oaExamine.setExamineRecordId(Convert.toLong(examineData.getRecordId()));
            oaExamine.setUpdateTime(LocalDateTimeUtil.now());
            if (ExamineFlagEnum.DRAFT.getType().equals(oldOaExamine.getExamineFlag())) {
                //清除草稿
                oaExamine.setExamineFlag(ExamineFlagEnum.NORMAL.getType());
                oaExamine.setExamineFlowDataDraft("");
            }
            updateById(oaExamine);
            examineTravelService.lambdaUpdate().eq(OaExamineTravel::getExamineId, examineId).remove();
            deleteOaExamineRelation(examineId);

            operationLog.setOperationObject(oaExamine.getContent());
            operationLog.setOperationInfo("编辑审批：" + oaExamine.getContent());
            operationLog.setBehavior(BehaviorEnum.UPDATE);
        }
        // 判断审批关系是否为null
        String oaExamineR = "oaExamineRelation";
        if (jsonObject.get(oaExamineR) != null) {
            OaExamineRelation oaExamineRelation = jsonObject.getObject("oaExamineRelation", OaExamineRelation.class);
            // 添加审批关系
            addOaExamineRelation(examineId, oaExamineRelation);
            // 反推活动数据
            addActivity(oaExamine, oaExamineRelation);
        }
        if (oaExamineTravelList != null) {
            for (Object json : oaExamineTravelList) {
                OaExamineTravel oaExamineTravel = TypeUtils.castToJavaBean(json, OaExamineTravel.class);
                oaExamineTravel.setTravelId(null);
                oaExamineTravel.setExamineId(examineId);
                examineTravelService.save(oaExamineTravel);
            }
        }
        return operationLog;
    }

    /**
     * 添加活动数据
     *
     * @param oaExamine         审批数据
     * @param oaExamineRelation 审批关联业务
     */
    private void addActivity(OaExamine oaExamine, OaExamineRelation oaExamineRelation) {
        //crmService.addActivity(2, 9, oaExamine.getExamineId());
        ExamineInfoVo examineInfoVo = examineService.queryExamineById(oaExamine.getCategoryId()).getData();
        Integer oaType = examineInfoVo.getOaType();
        ActivityContent activityContent = null;
        //1 普通审批 2 请假审批 3 出差审批 4 加班审批 5 差旅报销 6 借款申请
        switch (oaType) {
            case 0:
                activityContent = new ActivityContent(examineInfoVo.getExamineName()
                        , oaExamine.getExamineStatus(), oaType, 9, oaExamine.getContent());
                break;
            case 1:
                activityContent = new ActivityContent(examineInfoVo.getExamineName()
                        , oaExamine.getExamineStatus(), oaType, 9, oaExamine.getContent());
                break;
            case 2:
                //crmService.addActivity(2, 9, oaExamine.getExamineId());
                return;
            case 3:
                activityContent = new ActivityContent(examineInfoVo.getExamineName()
                        , oaExamine.getExamineStatus(), oaType, 9, oaExamine.getContent(), oaExamine.getDuration(), "");
                break;
            case 4:
                activityContent = new ActivityContent(examineInfoVo.getExamineName()
                        , oaExamine.getExamineStatus(), oaType, 9, oaExamine.getContent(), LocalDateTimeUtil.formatNormal(oaExamine.getStartTime()), LocalDateTimeUtil.formatNormal(oaExamine.getEndTime()));
                break;
            case 5:
                activityContent = new ActivityContent(examineInfoVo.getExamineName()
                        , oaExamine.getExamineStatus(), oaType, 9, oaExamine.getContent(), oaExamine.getMoney());
                break;
            case 6:
                //crmService.addActivity(2, 9, oaExamine.getExamineId());
                return;
            default:
                break;
        }
        CrmActivityBO crmActivityBO = new CrmActivityBO(2, 9, oaExamine.getExamineId(), activityContent);

        //获得关联业务
        if (!ObjectUtil.isEmpty(oaExamineRelation.getBusinessIds())) {
            Set<Long> longs = SeparatorUtil.toLongSet(oaExamineRelation.getBusinessIds());
            crmActivityBO.setBusinessIds(new ArrayList<>(longs));
        }

        if (!ObjectUtil.isEmpty(oaExamineRelation.getContactsIds())) {
            Set<Long> longs = SeparatorUtil.toLongSet(oaExamineRelation.getContactsIds());
            crmActivityBO.setContactsIds(new ArrayList<>(longs));
        }

        if (!ObjectUtil.isEmpty(oaExamineRelation.getContractIds())) {
            Set<Long> longs = SeparatorUtil.toLongSet(oaExamineRelation.getContractIds());
            crmActivityBO.setContractIds(new ArrayList<>(longs));
        }

        if (!ObjectUtil.isEmpty(oaExamineRelation.getCustomerIds())) {
            Set<Long> longs = SeparatorUtil.toLongSet(oaExamineRelation.getCustomerIds());
            crmActivityBO.setCustomerIds(new ArrayList<>(longs));
        }
    }

    /**
     * 添加审批关系
     *
     * @param examineId         审批id
     * @param oaExamineRelation 审批关系对象
     * @author jiao sir
     * @date 2021/11/19
     */
    private void addOaExamineRelation(Long examineId, OaExamineRelation oaExamineRelation) {
        // 获取关联的业务转集合//TODO 可以让前端直接传入集合
        List<OaExamineRelation> oaExamineRelationList = new ArrayList<>(16);
        // 处理审批关联
        handleOaExamineRelation(examineId, CrmRelationTypeEnum.CUSTOMER.getType(), oaExamineRelation.getCustomerIds(), oaExamineRelationList);
        handleOaExamineRelation(examineId, CrmRelationTypeEnum.CONTACTS.getType(), oaExamineRelation.getContactsIds(), oaExamineRelationList);
        handleOaExamineRelation(examineId, CrmRelationTypeEnum.BUSINESS.getType(), oaExamineRelation.getBusinessIds(), oaExamineRelationList);
        handleOaExamineRelation(examineId, CrmRelationTypeEnum.CONTRACT.getType(), oaExamineRelation.getContractIds(), oaExamineRelationList);
        examineRelationService.saveBatch(oaExamineRelationList, oaExamineRelationList.size());
    }

    /**
     * 根据审批id删除审批关系
     *
     * @param examineId 审批id
     * @author jiao sir
     * @date 2021/11/19
     */
    private void deleteOaExamineRelation(Long examineId) {
        examineRelationService.lambdaUpdate()
                .eq(OaExamineRelation::getExamineId, examineId)
                .remove();
    }

    /**
     * 处理审批关联
     *
     * @param examineId             审批id
     * @param type                  类型
     * @param relationIds           关系ids
     * @param oaExamineRelationList 关系列表
     * @author jiao sir
     * @date 2021/11/19
     */
    private void handleOaExamineRelation(Long examineId, int type, String relationIds, List<OaExamineRelation> oaExamineRelationList) {
        SeparatorUtil.toLongSet(relationIds)
                .forEach(id -> oaExamineRelationList.add(OaExamineRelation
                        .builder()
                        .examineId(examineId)
                        .type(type)
                        .relationId(id)
                        .build()));
    }


    /**
     * 补充审批字段信息
     *
     * @param label
     * @param typeId
     * @param recordId
     * @param examineRecordSaveBO
     * @return void
     * @date 2020/12/18 13:44
     **/
    public void supplementFieldInfo(Integer label, Long typeId, Long recordId, ExamineRecordSaveBO examineRecordSaveBO) {
        examineRecordSaveBO.setLabel(label);
        examineRecordSaveBO.setTypeId(typeId);
        examineRecordSaveBO.setRecordId(recordId);
        if (examineRecordSaveBO.getDataMap() != null) {
            examineRecordSaveBO.getDataMap().put("createUserId", UserUtil.getUserId());
        } else {
            Map<String, Object> entityMap = new HashMap<>(1);
            entityMap.put("createUserId", UserUtil.getUserId());
            examineRecordSaveBO.setDataMap(entityMap);
        }
    }

    /**
     * @param examineType 1 待审核 2 通过 3 拒绝
     */
    public void addMessage(Integer examineType, Object examineObj, Long ownerUserId) {
        AdminMessageBO adminMessageBO = new AdminMessageBO();
        adminMessageBO.setUserId(ownerUserId);
        if (examineType == 1) {
            if (examineObj instanceof OaExamineLog) {
                OaExamineLog examineLog = (OaExamineLog) examineObj;
                OaExamineRecord examineRecord = examineRecordService.getById(examineLog.getRecordId());
                if (examineRecord == null) {
                    return;
                }
                OaExamine examine = getById(examineRecord.getExamineId());
                if (examine == null) {
                    return;
                }
                OaExamineCategory examineCategory = examineCategoryService.getById(examine.getCategoryId());
                if (examineCategory == null) {
                    return;
                }
                adminMessageBO.setTitle(examineCategory.getTitle());
                adminMessageBO.setTypeId(examine.getExamineId());
                adminMessageBO.setMessageType(AdminMessageEnum.OA_EXAMINE_NOTICE.getType());
                adminMessageBO.setIds(Collections.singletonList(examineLog.getExamineUser()));
            }
        } else if (examineType == TWO || examineType == THREE) {
            if (examineObj instanceof OaExamineRecord) {
                OaExamineRecord examineRecord = (OaExamineRecord) examineObj;
                OaExamine examine = getById(examineRecord.getExamineId());
                if (examine == null) {
                    return;
                }
                OaExamineCategory examineCategory = examineCategoryService.getById(examine.getCategoryId());
                if (examineCategory == null) {
                    return;
                }
                adminMessageBO.setMessageType(examineType == 2 ? AdminMessageEnum.OA_EXAMINE_PASS.getType() : AdminMessageEnum.OA_EXAMINE_REJECT.getType());
                adminMessageBO.setContent(examineRecord.getRemarks());
                adminMessageBO.setTitle(examineCategory.getTitle());
                adminMessageBO.setTypeId(examine.getExamineId());
                adminMessageBO.setIds(Collections.singletonList(examine.getCreateUserId()));

            }
        }
        if (adminMessageBO.getIds().size() > 0) {
            AdminMessageService messageService = ApplicationContextHolder.getBean(AdminMessageService.class);
            messageService.sendMessage(adminMessageBO);
        }
    }

    private void saveField(OaExamine oaExamine, JSONArray array, String batchId) {
        saveField(oaExamine, array, batchId, false);
    }

    /**
     * 保存自定义字段
     *
     * @param array   参数对象
     * @param batchId 批次ID
     */
    private void saveField(OaExamine oaExamine, JSONArray array, String batchId, boolean isUpdate) {

        if (array == null || StrUtil.isEmpty(batchId)) {
            return;
        }
        List<OaExamineField> oaExamineFields = JSONArray.parseArray(array.toJSONString(), OaExamineField.class);
        if (isUpdate) {
            List<OaExamineData> examineData = examineDataService.lambdaQuery().eq(OaExamineData::getBatchId, batchId).list();
            List<Long> deleteIds = new ArrayList<>();
            for (OaExamineData examineDatum : examineData) {
                for (OaExamineField examineField : oaExamineFields) {
                    if (examineDatum.getFieldId().equals(examineField.getFieldId())) {
                        deleteIds.add(examineDatum.getId());
                    }
                }
            }
            removeByIds(deleteIds);
        } else {
            examineDataService.lambdaUpdate().eq(OaExamineData::getBatchId, batchId).remove();
        }


        List<OaExamineData> fieldvs = new ArrayList<>();
        Map<String, OaExamineField> fieldMap = oaExamineFields.stream().collect(Collectors.toMap(OaExamineField::getName, Function.identity(), (v1, v2) -> v2));
        oaExamineFields.forEach(oaExamineField -> {
            OaExamineData fieldv = BeanUtil.copyProperties(oaExamineField, OaExamineData.class);
            if (FieldEnum.SERIAL_NUMBER.getType().equals(oaExamineField.getType())) {
                // 自定义字段值
                if (ObjectUtil.isNotEmpty(oaExamineField)) {
                    Map<String, Object> map = BeanUtil.beanToMap(oaExamineField);
                    map.put("batchId", batchId);
                    if (ObjectUtil.isEmpty(oaExamineField.getOptions())) {
                        OaExamineField byId = oaExamineFieldService.getById(oaExamineField.getFieldId());
                        if (ObjectUtil.isNotEmpty(byId)) {
                            oaExamineField.setOptions(byId.getOptions());
                        }
                    }
                    OaLogTemplateFieldVO oaLogTemplateFieldVO = BeanUtil.copyProperties(oaExamineField, OaLogTemplateFieldVO.class);
                    List<OaLogFieldNumberDataServiceImpl.FieldNumberSetting> fieldNumberSettingList = JSON.parseArray(oaLogTemplateFieldVO.getOptions(), OaLogFieldNumberDataServiceImpl.FieldNumberSetting.class);
                    if (CollectionUtil.isNotEmpty(fieldNumberSettingList)) {
                        for (OaLogFieldNumberDataServiceImpl.FieldNumberSetting numberSetting : fieldNumberSettingList) {
                            if (numberSetting.getType() == 3) {
                                if (ObjectUtil.isNotEmpty(numberSetting.getValue()) && numberSetting.getValue().equals("创建时间")) {
                                    numberSetting.setValue("createTime");
                                    if (ObjectUtil.isEmpty(oaExamine.getCreateTime())) {
                                        map.put("createTime", LocalDateTime.now());
                                    } else {
                                        map.put("createTime", oaExamine.getCreateTime());
                                    }
                                }
                                if (ObjectUtil.isNotEmpty(numberSetting.getValue()) && numberSetting.getValue().equals("密级")) {
                                    if (fieldMap.containsKey(numberSetting.getValue())) {
                                        OaExamineField examineField = fieldMap.get(numberSetting.getValue());
                                        numberSetting.setValue(examineField.getFieldName());
                                        map.put(examineField.getFieldName(), examineField.getValue());
                                    }
                                }
                                if (ObjectUtil.isNotEmpty(numberSetting.getValue()) && numberSetting.getValue().equals("紧急程度")) {
                                    if (fieldMap.containsKey(numberSetting.getValue())) {
                                        OaExamineField examineField = fieldMap.get(numberSetting.getValue());
                                        numberSetting.setValue(examineField.getFieldName());
                                        map.put(examineField.getFieldName(), examineField.getValue());
                                    }
                                }
                                if (ObjectUtil.isNotEmpty(numberSetting.getValue()) && numberSetting.getValue().equals("提交时间")) {
                                    numberSetting.setValue("submitTime");
                                    if (ObjectUtil.isEmpty(oaExamine.getSubmitTime())) {
                                        map.put("submitTime", LocalDateTime.now());
                                    } else {
                                        map.put("submitTime", oaExamine.getSubmitTime());
                                    }
                                }
                            }
                        }
                    }
                    oaLogTemplateFieldVO.setOptions(JSON.toJSONString(fieldNumberSettingList));
                    String generateNumber = getBean(IOaLogFieldNumberDataService.class).generateNumber(oaLogTemplateFieldVO, map);
                    fieldv.setValue(generateNumber);
                }
            } else {
                fieldv.setValue(FieldUtil.format2DbString(oaExamineField.getValue(), oaExamineField.getType(), fieldv.getValue()));
            }
            fieldv.setId(null);
            fieldv.setCreateTime(LocalDateTimeUtil.now());
            fieldv.setBatchId(batchId);
            fieldvs.add(fieldv);
        });
        examineDataService.saveBatch(fieldvs, 100);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void oaExamine(AuditExamineBO auditExamineBO) {
        OaExamineLog nowadayExamineLog = new OaExamineLog();
        nowadayExamineLog.setRecordId(auditExamineBO.getRecordId());
        nowadayExamineLog.setExamineStatus(auditExamineBO.getStatus());
        nowadayExamineLog.setRemarks(auditExamineBO.getRemarks());
        Long nextUserId = auditExamineBO.getNextUserId();
        Long auditUserId = UserUtil.getUserId();
        String checkUserIds = "";
        if (nextUserId != null) {
            checkUserIds = nextUserId + "";
        }
        Long recordId = nowadayExamineLog.getRecordId();
        Integer status = nowadayExamineLog.getExamineStatus();
        //根据审核记录id查询审核记录
        OaExamineRecord examineRecord = examineRecordService.getById(recordId);
        //审核状态 0 未审核 1 审核通过 2 审核拒绝4 撤回审核
        if (status == FOUR) {
            if (!examineRecord.getCreateUser().equals(auditUserId) && !auditUserId.equals(UserUtil.getSuperUser())) {
                throw new CrmException(OaCodeEnum.CURRENT_USER_DOES_NOT_HAVE_APPROVAL_AUTHORITY);
            }
        } else {
            OaExamineLog oaExamineLog = examineLogService.lambdaQuery().eq(OaExamineLog::getRecordId, recordId).eq(OaExamineLog::getExamineUser, auditUserId)
                    .eq(examineRecord.getExamineStepId() != null, OaExamineLog::getExamineStepId, examineRecord.getExamineStepId()).eq(OaExamineLog::getExamineStatus, 0)
                    .ne(OaExamineLog::getIsRecheck, 1).orderByDesc(OaExamineLog::getCreateTime).one();
            //【判断当前审批人是否有审批权限
            if (oaExamineLog == null) {
                throw new CrmException(OaCodeEnum.CURRENT_USER_DOES_NOT_HAVE_APPROVAL_AUTHORITY);
            }
        }
        examineRecord.setExamineStatus(status);
        Long examineId = examineRecord.getExamineId();
        //查询审批流程
        OaExamine examine = getById(examineId);
        //查询审批类型
        OaExamineCategory examineCategory = examineCategoryService.getById(examine.getCategoryId());
        //查询当前审批步骤
        OaExamineStep examineStep = examineStepService.getById(examineRecord.getExamineStepId());
        //查询当前审核日志
        Long createUserId = examine.getCreateUserId();
        OaExamineLog log;
        if (examineCategory.getExamineType() == 1) {
            log = examineLogService.lambdaQuery().eq(OaExamineLog::getRecordId, examineRecord.getRecordId())
                    .eq(OaExamineLog::getExamineStepId, examineRecord.getExamineStepId())
                    .eq(OaExamineLog::getExamineUser, auditUserId).eq(OaExamineLog::getIsRecheck, 0).one();
        } else {
            log = examineLogService.lambdaQuery().eq(OaExamineLog::getRecordId, examineRecord.getRecordId())
                    .eq(OaExamineLog::getExamineUser, auditUserId)
                    .eq(OaExamineLog::getExamineStatus, 0)
                    .eq(OaExamineLog::getIsRecheck, 0)
                    .one();
        }
        nowadayExamineLog.setExamineUser(auditUserId);
        if (log != null) {
            nowadayExamineLog.setLogId(log.getLogId());
            nowadayExamineLog.setOrderId(log.getOrderId());
        }

        //审核日志 添加审核人
        nowadayExamineLog.setExamineTime(LocalDateTimeUtil.now());
        if (status != FOUR) {
            examineLogService.updateById(nowadayExamineLog);
        }
        if (status == TWO) {
            //判断审核拒绝
            if (examineStep != null && examineStep.getStepType() == TWO) {
                Integer toCount = examineLogMapper.queryCountByStepId(recordId, examineStep.getStepId());
                if (toCount == 0) {
                    examineRecord.setExamineStatus(status);
                }
            }
        } else if (status == FOUR) {
            examineRecord.setExamineStatus(4);
            //先查询该审批流程的审批步骤的第一步
            OaExamineStep oneExamineStep = examineStepService.lambdaQuery().eq(OaExamineStep::getCategoryId, examine.getCategoryId()).orderByAsc(OaExamineStep::getStepNum).one();
            //判断审核撤回
            OaExamineLog examineLog = new OaExamineLog();
            examineLog.setExamineUser(auditUserId);
            examineLog.setCreateTime(LocalDateTimeUtil.now());
            examineLog.setCreateUser(auditUserId);
            examineLog.setExamineStatus(status);
            examineLog.setIsRecheck(1);
            examineLog.setExamineTime(LocalDateTimeUtil.now());
            if (examineCategory.getExamineType() == 1) {
                examineRecord.setExamineStepId(oneExamineStep.getStepId());
                examineLog.setExamineStepId(examineStep.getStepId());
                examineLog.setOrderId(examineStep.getStepNum());
            } else {
                Integer orderId;
                Optional<OaExamineLog> oaExamineLogOpt = examineLogService.lambdaQuery().eq(OaExamineLog::getRecordId, recordId).eq(OaExamineLog::getIsRecheck, 0).ne(OaExamineLog::getExamineStatus, 0)
                        .orderByDesc(OaExamineLog::getOrderId).oneOpt();
                if (oaExamineLogOpt.isPresent()) {
                    orderId = oaExamineLogOpt.get().getOrderId();
                } else {
                    orderId = 1;
                }
                examineLog.setOrderId(orderId);
            }
            examineLog.setRecordId(examineRecord.getRecordId());
            examineLog.setRemarks(nowadayExamineLog.getRemarks());
            examineLogService.save(examineLog);
            //更新审核日志状态
            examineLogService.lambdaUpdate().set(OaExamineLog::getIsRecheck, 1).eq(OaExamineLog::getRecordId, recordId).update();
        } else {
            //审核通过
            //判断该审批流程类型
            OaExamineStep nextExamineStep = null;
            boolean flag = true;
            if (examineCategory.getExamineType() == 1) {
                //固定审批
                //查询下一个审批步骤
                nextExamineStep = examineStepService.queryExamineStepByNextExamineIdOrderByStepId(examineCategory.getCategoryId(), examineRecord.getExamineStepId());
                //判断是否是并签
                if (examineStep.getStepType() == THREE) {
                    //查询当前并签是否都完成
                    //当前并签人员
                    for (Long userId : SeparatorUtil.toLongSet(examineStep.getCheckUserId())) {
                        OaExamineLog examineLog = examineLogService.lambdaQuery().eq(OaExamineLog::getRecordId, examineRecord.getRecordId())
                                .eq(OaExamineLog::getExamineStepId, examineRecord.getExamineStepId()).eq(OaExamineLog::getExamineUser, userId)
                                .ne(OaExamineLog::getIsRecheck, 1).one();
                        if (examineLog.getExamineStatus() == 0) {
                            //并签未走完
                            flag = false;
                            break;
                        }
                    }
                    //并签未完成
                    if (!flag) {
                        examineRecord.setExamineStatus(3);
                    }
                }
                if (flag) {
                    //判断是否有下一步流程
                    if (nextExamineStep != null) {
                        //有下一步流程
                        examineRecord.setExamineStatus(3);
                        examineRecord.setExamineStepId(nextExamineStep.getStepId());
                        Integer stepType = nextExamineStep.getStepType();
                        //生成审批日志
                        if (stepType == 1) {
                            checkUserIds = UserCacheUtil.getUserInfo(createUserId).getParentId() + "";
                        } else if (stepType == FOUR) {
                            UserInfo adminUser = UserCacheUtil.getUserInfo(nowadayExamineLog.getExamineUser());
                            if (adminUser != null && adminUser.getParentId() != null) {
                                checkUserIds = adminUser.getParentId() + "";
                            } else {
                                checkUserIds = UserUtil.getSuperUser() + "";
                            }
                        } else {
                            checkUserIds = nextExamineStep.getCheckUserId();
                        }
                    }
                    String zero = "0";
                    if (zero.equals(checkUserIds)) {
                        checkUserIds = UserUtil.getSuperUser() + "";
                    }
                }
            }
            if (((examineCategory.getExamineType() == TWO) || (examineCategory.getExamineType() == 1 && flag)) && StrUtil.isEmpty(checkUserIds)) {
                //没有上级，审核通过
                examineRecord.setExamineStatus(1);
            } else {
                examineRecord.setExamineStatus(3);
                //添加审核日志
                for (Long userId : SeparatorUtil.toLongSet(checkUserIds)) {
                    OaExamineLog oaExamineLog = new OaExamineLog();
                    oaExamineLog.setRecordId(examineRecord.getRecordId());
                    oaExamineLog.setOrderId(nowadayExamineLog.getOrderId() + 1);
                    if (nextExamineStep != null) {
                        oaExamineLog.setOrderId(nextExamineStep.getStepNum());
                        oaExamineLog.setExamineStepId(nextExamineStep.getStepId());
                    }
                    oaExamineLog.setExamineStatus(0);
                    oaExamineLog.setCreateUser(UserUtil.getUserId());
                    oaExamineLog.setCreateTime(LocalDateTimeUtil.now());
                    oaExamineLog.setExamineUser(userId);
                    examineLogService.save(oaExamineLog);
                    addMessage(1, oaExamineLog, examine.getCreateUserId());
                }
            }

        }
        examineRecord.setRemarks(nowadayExamineLog.getRemarks());
        if (examineRecord.getExamineStatus().equals(1)) {
            addMessage(2, examineRecord, auditUserId);
        } else if (examineRecord.getExamineStatus().equals(TWO)) {
            addMessage(3, examineRecord, auditUserId);
        }
        examineRecord.setRemarks(null);
        examineRecordService.updateById(examineRecord);
    }

    @Override
    public ExamineVO queryOaExamineInfo(String id) {
        OaExamine oaExamine = examineMapper.selectById(id);
        if (oaExamine == null) {
            throw new CrmException(OaCodeEnum.EXAMINE_ALREADY_DELETE);
        }
        ExamineVO examineVO = new ExamineVO();
        BeanUtil.copyProperties(oaExamine, examineVO);
        SimpleUser simpleUser = UserCacheUtil.getSimpleUser(examineVO.getCreateUserId());
        examineVO.setCreateUser(simpleUser);
        examineVO.setSubmitDeptName(UserCacheUtil.getDeptName(examineVO.getSubmitDeptId()));
        String batchId = oaExamine.getBatchId();
        setRelation(examineVO);
        ExamineInfoVo examineInfoVo = examineService.queryExamineById(Long.valueOf(oaExamine.getCategoryId())).getData();
        String title = "";
        if (examineInfoVo != null) {
            title = examineInfoVo.getExamineName();
            examineVO.setExamineIcon(examineInfoVo.getExamineIcon());
            examineVO.setType(examineInfoVo.getOaType());
        }
        examineVO.setCategoryTitle(title);
        Result<List<FileEntity>> fileEntityResult = adminFileService.queryFileList(batchId);
        Map<String, List<FileEntity>> collect = fileEntityResult.getData().stream().collect(Collectors.groupingBy(FileEntity::getFileType));
        if (collect.containsKey(IMG)) {
            examineVO.setImg(collect.get(IMG));
        } else {
            examineVO.setImg(new ArrayList<>());
        }
        if (collect.containsKey(FILE)) {
            examineVO.setFile(collect.get(FILE));
        } else {
            examineVO.setFile(new ArrayList<>());
        }
        List<OaExamineTravel> examineTravelList = examineTravelService.lambdaQuery().eq(OaExamineTravel::getExamineId, id).list();
        examineTravelList.forEach(travel -> {
            if (StrUtil.isNotEmpty(travel.getBatchId())) {
                List<FileEntity> fileEntities = adminFileService.queryFileList(travel.getBatchId()).getData();
                Map<String, List<FileEntity>> listMap = fileEntities.stream().collect(Collectors.groupingBy(FileEntity::getFileType));
                if (listMap.containsKey(IMG)) {
                    travel.setImg(listMap.get(IMG));
                } else {
                    travel.setImg(new ArrayList<>());
                }
                if (listMap.containsKey(FILE)) {
                    travel.setFile(listMap.get(FILE));
                } else {
                    travel.setFile(new ArrayList<>());
                }
            }
        });
        examineVO.setExamineTravelList(examineTravelList);
        List<ExamineVO> examineVOS = transfer(Collections.singletonList(examineVO));
        return examineVOS.get(0);
    }

    @Override
    public JSONObject queryExamineRecordList(String recordId) {
        JSONObject jsonObject = new JSONObject();
        JSONObject examineRecord = examineMapper.queryExamineRecordById(recordId);
        Integer examineStatus = examineRecord.getInteger("examineStatus");
        //如果当前审批已撤回
        if (examineRecord.getInteger(EXAMINE_STATUS) == FOUR) {
            jsonObject.put("examineType", 1);
            JSONObject user = examineLogMapper.queryUserByRecordId(recordId);
            examineRecord.put("userList", user);
            List<JSONObject> records = new ArrayList<>();
            records.add(examineRecord);
            jsonObject.put("steps", records);
            return jsonObject;
        }
        OaExamine oaExamine = getById(examineRecord.getInteger("examineId"));
        OaExamineCategory oaExamineCategory = examineCategoryService.getById(oaExamine.getCategoryId());
        List<JSONObject> list = new ArrayList<>();
        JSONObject rec = examineLogMapper.queryRecordAndId(recordId);
        Long auditUserId = UserUtil.getUserId();
        //jsonObject.put("isRecheck",0);
        //判断是否有撤回权限
        String createUser = "createUser";
        if ((auditUserId.equals(examineRecord.getLong(createUser)) || auditUserId.equals(UserUtil.getSuperUser())) && (examineStatus == 0 || examineStatus == THREE)) {
            jsonObject.put("isRecheck", 1);
        } else {
            jsonObject.put("isRecheck", 0);
        }
        if (oaExamineCategory.getExamineType() == TWO) {
            JSONObject log = examineLogMapper.queryRecordByUserIdAndStatus(rec.getLong("createUser"), rec.getDate("examineTime"));
            rec.put("examinUser", log);
            list.add(rec);
            //授权审批
            List<JSONObject> logs = examineLogMapper.queryExamineLogAndUserByRecordId(recordId);
            logs.forEach(r -> {
                JSONObject i = examineLogMapper.queryExamineLogAndUserByLogId(r.getInteger("logId"));
                r.put("examinUser", i);
            });
            list.addAll(logs);
            OaExamineLog oaExamineLog = examineLogMapper.queryExamineLog(Integer.valueOf(recordId), auditUserId, examineRecord.getInteger("examineStepId"));
            if (oaExamineLog != null) {
                jsonObject.put("isCheck", 1);
            } else {
                jsonObject.put("isCheck", 0);
            }
            jsonObject.put("examineType", 2);
            jsonObject.put("steps", list);
        } else {
            jsonObject.put("examineType", 1);
            //固定审批
            List<Map<String, Object>> steps = examineStepService.listMaps(new LambdaQueryWrapper<OaExamineStep>()
                    .eq(OaExamineStep::getCategoryId, oaExamineCategory.getCategoryId()).orderByAsc(OaExamineStep::getStepNum));
            steps.forEach(step -> {
                if (ObjectUtil.equal(step.get(STEP_TYPE), 1)) {
                    //负责人主管
                    List<JSONObject> logs = examineLogMapper.queryUserByRecordIdAndStepIdAndStatus(recordId, (Long) step.get("stepId"));
                    //已经创建审核日志
                    if (logs != null && logs.size() > 0) {
                        for (JSONObject record : logs) {
                            step.put("examineStatus", record.getInteger("examineStatus"));
                        }
                        step.put("userList", logs);
                    } else {
                        step.put("examineStatus", 0);
                        //还未创建审核日志
                        //查询负责人主管
                        List<JSONObject> r = examineLogMapper.queryUserByUserId(oaExamine.getCreateUserId());
                        if (r == null || r.size() == 0) {
                            r = examineLogMapper.queryUserByUserId(UserUtil.getSuperUser());
                        }
                        step.put("userList", r);
                    }
                } else if (ObjectUtil.equal(step.get(STEP_TYPE), TWO) || ObjectUtil.equal(step.get(STEP_TYPE), THREE)) {
                    //先判断是否已经审核过
                    List<JSONObject> logs = examineLogMapper.queryUserByRecordIdAndStepIdAndStatus(recordId, (long) step.get("stepId"));
                    if (logs != null && logs.size() != 0) {
                        //已经创建审核日志
                        int status = 0;
                        if (ObjectUtil.equal(step.get(STEP_TYPE), TWO)) {
                            Optional<JSONObject> optional = logs.stream().filter(log -> log.getDate("examineTime") != null).min(Comparator.comparingLong(log -> log.getDate("examineTime").getTime()));
                            if (optional.isPresent()) {
                                status = optional.get().getInteger("examineStatus");
                            }
                        }
                        if (ObjectUtil.equal(step.get(STEP_TYPE), THREE)) {
                            int i = 0;
                            for (JSONObject record : logs) {
                                if (record.getInteger("examineStatus") == 2) {
                                    status = 2;
                                }
                                if (record.getInteger("examineStatus") == 1) {
                                    i++;
                                }
                            }
                            if (i == logs.size()) {
                                status = 1;
                            }
                        }
                        step.put("examineStatus", status);
                        step.put("userList", logs);
                    } else {
                        //该步骤还未审核
                        logs = new ArrayList<>();
                        String checkUserId = "checkUserId";
                        for (Long userId : SeparatorUtil.toLongSet((String) step.get(checkUserId))) {
                            JSONObject jsonObject1 = examineLogMapper.queryUserByUserIdAndStatus(userId);
                            logs.add(jsonObject1);
                        }
                        step.put("examineStatus", 0);
                        step.put("userList", logs);
                    }
                } else {
                    //主管的主管
                    List<JSONObject> logs = examineLogMapper.queryUserByRecordIdAndStepIdAndStatus(recordId, (long) step.get("stepId"));
                    //已经创建审核日志
                    if (logs != null && logs.size() != 0) {
                        for (JSONObject record : logs) {
                            step.put("examineStatus", record.getInteger("examineStatus"));
                        }
                        step.put("userList", logs);
                    } else {
                        step.put("examine_status", 0);
                        //还未创建审核日志
                        //查询负责人主管的主管

                        OaExamineStep examineStep = examineStepService.getById((int) step.get("stepId"));
                        Long userId = queryStep(examineStep, Integer.valueOf(recordId), oaExamine.getCreateUserId());
                        //查询负责人主管的主管
                        JSONObject r = examineLogMapper.queryUserByUserIdAndStatus(userId);
                        step.put("userList", Collections.singletonList(r));
                    }
                }
            });
            OaExamineLog oaExamineLog = examineLogMapper.queryExamineLog(Integer.valueOf(recordId), auditUserId, examineRecord.getInteger("examineStepId"));
            if (oaExamineLog != null && (examineRecord.getInteger(EXAMINE_STATUS) == THREE || examineRecord.getInteger(EXAMINE_STATUS) == 0)) {
                jsonObject.put("isCheck", 1);
            } else {
                jsonObject.put("isCheck", 0);
            }
            JSONObject log = examineLogMapper.queryRecordByUserIdAndStatus(rec.getLong("createUser"), rec.getDate("examineTime"));
            rec.put("userList", Collections.singletonList(log));
            rec.put("stepType", 5);
            list.add(rec);
            List<JSONObject> jsonObjects = TransferUtil.transferList(steps, JSONObject.class);
            list.addAll(jsonObjects);
            jsonObject.put("steps", list);
        }
        return jsonObject;
    }

    /**
     * 递归查询上一审核人主管第一级审批步骤
     */
    private Long queryStep(OaExamineStep step, Integer recordId, Long ownerUserId) {
        Optional<OaExamineLog> oaExamineLogOpt = examineLogService.lambdaQuery().eq(OaExamineLog::getRecordId, recordId).eq(OaExamineLog::getExamineStepId, step.getStepId())
                .and(e -> e.eq(OaExamineLog::getIsRecheck, 0).or().isNull(OaExamineLog::getIsRecheck)).eq(OaExamineLog::getExamineStatus, 1)
                .orderByDesc(OaExamineLog::getLogId).oneOpt();
        if (!oaExamineLogOpt.isPresent()) {
            //获取上一个审核步骤
            OaExamineStep lastStep = examineStepService.lambdaQuery().eq(OaExamineStep::getCategoryId, step.getCategoryId())
                    .apply("and step_num =  (SELECT step_num FROM 72crm_oa_examine_step where step_id = {0}) - 1", step.getStepId()).one();
            if (lastStep == null) {
                UserInfo adminUser = UserCacheUtil.getUserInfo(ownerUserId);
                if (adminUser.getParentId() == null) {
                    return ownerUserId;
                } else {
                    return adminUser.getParentId();
                }
            }
            Long userId = queryStep(lastStep, recordId, ownerUserId);
            if (userId != null) {
                UserInfo adminUser = UserCacheUtil.getUserInfo(userId);
                if (adminUser.getParentId() == null) {
                    return userId;
                } else {
                    return adminUser.getParentId();
                }
            } else {
                UserInfo adminUser = UserCacheUtil.getUserInfo(ownerUserId);
                if (adminUser.getParentId() == null) {
                    return ownerUserId;
                } else {
                    return adminUser.getParentId();
                }
            }
        } else {
            //已经生成审核
            OaExamineLog r = oaExamineLogOpt.get();
            UserInfo adminUser = UserCacheUtil.getUserInfo(r.getExamineUser());
            if (adminUser.getParentId() == null) {
                return r.getExamineUser();
            } else {
                return adminUser.getParentId();
            }
        }
    }

    @Override
    public List<JSONObject> queryExamineLogList(Long recordId) {
        OaExamineRecord examineRecord = examineRecordService.getById(recordId);
        OaExamine examine = getById(examineRecord.getExamineId());
        OaExamineCategory category = examineCategoryService.getById(examine.getCategoryId());
        List<JSONObject> logs = new ArrayList<>();
        logs.add(new JSONObject().fluentPut("examine_status", 6).fluentPut("examine_time", examineRecord.getCreateTime()).fluentPut("orderId", 0).
                fluentPut("realname", UserCacheUtil.getUserName(examineRecord.getCreateUser()))
                .fluentPut("remarks", "").fluentPut("user_id", examineRecord.getCreateUser()));
        if (category.getExamineType() == 1) {
            logs.addAll(examineLogMapper.queryExamineLogByRecordIdByStep(recordId));
        } else {
            logs.addAll(examineLogMapper.queryExamineLogByRecordIdByStep1(recordId));
        }
        return logs;
    }

    @Override
    public OperationLog deleteOaExamine(Long examineId) {
        OaExamine examine = getById(examineId);
        //--------------------------------------------
        if (!examine.getExamineFlag().equals(ExamineFlagEnum.DRAFT.getType())) {
            boolean bol = examine.getExamineStatus() != 4 && (!UserUtil.isAdmin());
            if (bol) {
                throw new CrmException(SystemCodeEnum.SYSTEM_NO_AUTH);
            }
            examineDataService.lambdaUpdate().eq(OaExamineData::getBatchId, examine.getBatchId()).remove();
            removeById(examineId);
            // 删除审批关系
            deleteOaExamineRelation(examineId);
            examineTravelService.lambdaUpdate().eq(OaExamineTravel::getExamineId, examineId).remove();
            Long recordId = examine.getExamineRecordId();
            // 删除审批关系
            if (recordId != null) {
                examineService.deleteExamineRecord(recordId);
            }
        } else {
            if (!(examine.getCreateUserId().equals(UserUtil.getUserId()) || UserUtil.isAdmin())) {
                throw new CrmException(SystemCodeEnum.SYSTEM_NO_AUTH);
            }
            examineDataService.lambdaUpdate().eq(OaExamineData::getBatchId, examine.getBatchId()).remove();
            removeById(examineId);
            // 删除审批关系
            deleteOaExamineRelation(examineId);
            examineTravelService.lambdaUpdate().eq(OaExamineTravel::getExamineId, examineId).remove();
        }

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationInfo("删除审批" + examine.getContent());
        operationLog.setOperationObject(examine.getContent());
        return operationLog;
    }

    @Override
    public OaExamineCategory queryExaminStep(Long categoryId) {
        OaExamineCategory category = examineCategoryService.getById(categoryId);
        Integer examineType = category.getExamineType();
        if (examineType == 1) {
            List<OaExamineStep> list = examineStepService.lambdaQuery().eq(OaExamineStep::getCategoryId, categoryId).list();
            list.forEach(step -> {
                List<SimpleUser> userList = UserCacheUtil.getSimpleUsers(SeparatorUtil.toLongSet(step.getCheckUserId()));
                step.setUserList(userList);
            });
            category.setStepList(list);
        }
        return category;
    }

    @Override
    public List<Map<String, Object>> export(ExamineExportBO examineExportBO, ExamineInfoVo examineInfoVo, List<OaExamineField> fieldList) {
        Integer type = examineInfoVo.getOaType();
        Integer queryType = examineExportBO.getQueryType();
        List<JSONObject> examineList = new ArrayList<>();
        Long userId = UserUtil.getUserId();
        //我发出的
        if (queryType == 1) {
            examineList = examineMapper.myInitiateOaExcel(examineExportBO, userId, UserUtil.isAdmin());
            //待我审批的
        } else if (queryType == TWO) {
            List<Long> ids = examineService.queryOaExamineIdList(examineExportBO.getStatus(), examineExportBO.getCategoryId()).getData();
            if (CollUtil.isNotEmpty(ids)) {
                List<OaExamine> oaExamineList = oaExamineService.lambdaQuery().select(OaExamine::getExamineId, OaExamine::getBatchId, OaExamine::getStartTime, OaExamine::getEndTime).in(OaExamine::getExamineId, ids).list();
                for (OaExamine oaExamine : oaExamineList) {
                    examineList.add((JSONObject) JSON.toJSON(oaExamine));
                }
            }
        }
        List<Long> examineIdList = examineList.stream().map(record -> record.getLong("examineId")).collect(Collectors.toList());
        List<String> batchIdList = examineList.stream().map(record -> record.getString("batchId")).collect(Collectors.toList());
        if (examineIdList.size() == 0) {
            examineIdList.add(0L);
        }
        if (batchIdList.size() == 0) {
            batchIdList.add("");
        }
        List<JSONObject> recordList;
        // 根据审批类型不同 查询sql不同
        int five = 5;
        if (type == five || type == THREE) {
            recordList = examineMapper.queryTravelExamineList(examineIdList);
        } else if (type == 0) {
            List<OaExamineField> fields = fieldList.stream().filter(field -> field.getFieldType() != 1).collect(Collectors.toList());
            recordList = examineMapper.queryCustomExamineList(examineIdList,  batchIdList, fields);
        } else {
            recordList = examineMapper.queryExamineList(examineIdList);
        }
        // 查询审批关联的关系
        Map<Integer, Map<Long, Set<Long>>> relationIdsMap = examineRelationService.lambdaQuery()
                .select(OaExamineRelation::getRelationId, OaExamineRelation::getType, OaExamineRelation::getExamineId)
                .in(OaExamineRelation::getExamineId, examineIdList)
                .list()
                .stream()
                .collect(Collectors.groupingBy(OaExamineRelation::getType,
                        Collectors.groupingBy(OaExamineRelation::getExamineId, Collectors.mapping(OaExamineRelation::getRelationId, Collectors.toSet()))));
        // 查询关系数据
        Map<Long, CrmRelationDTO> oaCrmRelationMap = CrmRelationUtils.getCrmRelationMap(relationIdsMap, examineIdList);
        List<Map<String, Object>> list = new ArrayList<>();
        switch (type) {
            case 1:
                recordList.forEach(record -> {
                    record.put("category", "普通审批");
                    record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    list.add(record.getInnerMap());
                });
                break;
            case 2:
                recordList.forEach(record -> {
                    record.put("category", "请假审批-" + record.getString("typeId"));
                    record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    list.add(record.getInnerMap());
                });
                break;
            case 3:
                for (int i = 0; i < recordList.size(); i++) {
                    JSONObject record = recordList.get(i);
                    //同一审批，从第二个起前面重复字段不用再显示一遍
                    if (i > 0 && record.getInteger("examineId").equals(recordList.get(i - 1).getInteger("examineId"))) {
                        record.fluentPut("category", "").fluentPut("create_time", "").fluentPut("create_user_name", "").fluentPut("examine_status", "")
                                .fluentPut("examine_user_name", "").fluentPut("previous_examine_user_name", "").fluentPut("content", "")
                                .fluentPut("remark", "").fluentPut("duration", "").fluentPut("relateCrmWork", "");
                    } else {
                        record.put("category", "出差审批");
                        record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    }
                    list.add(record.getInnerMap());
                }
                break;
            case 4:
                recordList.forEach(record -> {
                    record.put("category", "加班审批");
                    record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    list.add(record.getInnerMap());
                });
                break;
            case 5:
                for (int i = 0; i < recordList.size(); i++) {
                    JSONObject record = recordList.get(i);
                    //同一审批，从第二个起前面重复字段不用再显示一遍
                    if (i > 0 && record.getInteger("examineId").equals(recordList.get(i - 1).getInteger("examineId"))) {
                        record.fluentPut("category", "").fluentPut("createTime", "").fluentPut("createUserName", "").fluentPut("examineStatus", "")
                                .fluentPut("examineUserName", "").fluentPut("previousExamineUserName", "").fluentPut("content", "")
                                .fluentPut("money", "").fluentPut("remark", "").fluentPut("relateCrmWork", "");
                    } else {
                        record.fluentPut("category", "差旅报销");
                        record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    }
                    list.add(record.getInnerMap());
                }
                break;
            case 6:
                recordList.forEach(record -> {
                    record.put("category", "借款申请");
                    record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    list.add(record.getInnerMap());
                });
                break;
            case 0:
                recordList.forEach(record -> {
                    record.put("category", examineInfoVo.getExamineName());
                    record.put("relateCrmWork", CrmRelationUtils.getRelateCrmWork(oaCrmRelationMap.get(record.getLong("examineId"))));
                    list.add(record.getInnerMap());
                });
                break;
            default:
                break;
        }
        list.forEach(this::supplementExamineInfoForExport);
        return list;
    }


    private void supplementExamineInfoForExport(Map<String, Object> map) {
        Object examineRecordId = map.get("examineRecordId");
        if (examineRecordId == null) {
            map.put("examineUserName", "");
            return;
        }
        Object examineStatus = map.get("examineStatusBack");
        if (examineStatus == null) {
            examineStatus = -1;
        }
        ExamineRecordReturnVO recordReturnVO = examineService.queryExamineRecordInfo(Convert.toLong(examineRecordId)).getData();
        List<Long> userIds = recordReturnVO.getExamineUserIds();
        String examineName = "";
        if (CollUtil.isNotEmpty(userIds) && (Integer) examineStatus != FOUR) {
            List<SimpleUser> userList = UserCacheUtil.getSimpleUsers(userIds);
            examineName = userList.stream().map(SimpleUser::getRealname).collect(Collectors.joining(","));
        }
        if ((Integer) examineStatus == FOUR) {
            Object createUserName = map.get("createUserName");
            examineName = createUserName != null ? createUserName.toString() : "";
        }
        map.put("examineUserName", examineName);
    }

    @Override
    public Map<String, Object> getDataMapForNewExamine(ExamineConditionDataBO examineConditionDataBO) {
        Map<String, Object> dataMap = new HashMap<>(8);
        Long id = examineConditionDataBO.getTypeId();
        Long categoryId = examineConditionDataBO.getCategoryId();
        List<String> fieldList = examineConditionDataBO.getFieldList();
        OaExamine oaExamine = this.getById(id);
        if (oaExamine == null) {
            throw new CrmException(OaCodeEnum.EXAMINE_ALREADY_DELETE);
        }
        List<OaExamineField> examineFields = examineFieldService.queryField(categoryId, Boolean.FALSE);
        Map<Long, String> fieldData = examineFieldService.queryFieldData(oaExamine.getBatchId());
        examineFields.forEach(field -> {
            if (CONTENT.equals(field.getFieldName())) {
                field.setValue(oaExamine.getContent());
            } else if (REMARK.equals(field.getFieldName())) {
                field.setValue(oaExamine.getRemark());
            } else {
                field.setValue(Optional.ofNullable(fieldData.get(field.getFieldId())).orElse(""));
            }
            field.setFieldName(StrUtil.toCamelCase(field.getFieldName()));
        });
        examineFieldService.transferFieldList(examineFields, 2);
        for (String field : fieldList) {
            for (OaExamineField examineField : examineFields) {
                if (field.equals(examineField.getFieldName())) {
                    dataMap.put(field, examineField.getValue());
                    break;
                }
            }
            Map<String, Object> examine = BeanUtil.beanToMap(oaExamine);
            Object value = examine.get(field);
            if (ObjectUtil.isNotEmpty(value)) {
                dataMap.put(field, examine.get(field));
            }
        }
        dataMap.put("createUserId", oaExamine.getCreateUserId());
        return dataMap;
    }

    @Override
    public Boolean updateCheckStatusByNewExamine(ExamineConditionDataBO examineConditionDataBO) {
        Long typeId = examineConditionDataBO.getTypeId();
        OaExamine oaExamine = oaExamineService.getById(typeId);
        if (oaExamine != null) {
            oaExamine.setExamineStatus(examineConditionDataBO.getCheckStatus());
            setExamineFlag(oaExamine, examineConditionDataBO.getCheckStatus());
            return oaExamineService.updateById(oaExamine);
        }
        return false;
    }


    @Override
    public ExamineVO getOaExamineById(Long oaExamineId) {
        OaExamine oaExamine = examineMapper.selectById(oaExamineId);
        ExamineVO examineVO = new ExamineVO();
        if (oaExamine == null) {
            return examineVO;
        }
        BeanUtil.copyProperties(oaExamine, examineVO);
        List<ExamineVO> examineVoList = transfer(ListUtil.toList(examineVO));
        return examineVoList.get(0);
    }
    @Override
    public Map<Long,ExamineVO> getOaExamineMapByIds(List<Long> oaExamineIds){
        if(ObjectUtils.isEmpty(oaExamineIds)){
            return Maps.newHashMap();
        }
        List<OaExamine> oaExamines = this.listByIds(oaExamineIds);
        if(ObjectUtils.isEmpty(oaExamines)){
            return Maps.newHashMap();
        }
        Map<Long, ExamineVO> idMap = oaExamines.stream().collect(Collectors.toMap(o -> o.getExamineId(), o -> {
            ExamineVO examineVO = new ExamineVO();
            BeanUtil.copyProperties(o, examineVO);
            List<ExamineVO> examineVoList = transfer(ListUtil.toList(examineVO));
            return examineVoList.get(0);
        }));
        return idMap;
    }

    @Override
    public List<OaExamineVO> queryLeaveExamineList(Map<String, Object> map) {
        Long categoryId = Convert.toLong(map.get("examineFieldId"));
        Long typeFieldId = Convert.toLong(map.get("typeFieldId"));
        Long startTimeFieldId = Convert.toLong(map.get("startTimeFieldId"));
        Long endTimeFieldId = Convert.toLong(map.get("endTimeFieldId"));
        Long durationFieldId = Convert.toLong(map.get("durationFieldId"));
        Long remarkFieldId = Convert.toLong(map.get("remarkFieldId"));
        List<OaExamineVO> oaExamineList = examineMapper.queryLeaveExamineList(categoryId);
        for (OaExamineVO oaExamineVO : oaExamineList) {
            GetExamineFieldBO queryBO = new GetExamineFieldBO();
            queryBO.setExamineId(oaExamineVO.getExamineId());
            queryBO.setType("1");
            queryBO.setIsDetail(1);
            List<OaExamineField> fields = oaExamineService.getField(queryBO);
            for (OaExamineField field : fields) {
                Long fieldId = field.getFieldId();
                if (ObjectUtil.equal(fieldId, typeFieldId)) {
                    oaExamineVO.setTypeId(field.getValue().toString());
                } else if (ObjectUtil.equal(fieldId, startTimeFieldId)) {
                    oaExamineVO.setStartTime(field.getValue().toString());
                } else if (ObjectUtil.equal(fieldId, endTimeFieldId)) {
                    oaExamineVO.setEndTime(field.getValue().toString());
                } else if (ObjectUtil.equal(fieldId, durationFieldId)) {
                    oaExamineVO.setDuration(Convert.toBigDecimal(field.getValue()));
                } else if (ObjectUtil.equal(fieldId, remarkFieldId)) {
                    oaExamineVO.setRemark(field.getValue().toString());
                }
            }
        }
        return oaExamineList;
    }

    @Override
    public List<Map<String, Object>> getAllFieldLanguageRel() {
        List<Map<String, Object>> listMap = new ArrayList<>();

        List<OaExamineField> list = examineFieldService.list();
        List<ExamineInfoVo> examineInfoVos = examineService.queryAllNormalExamine().getData();

        //审批流程
        if (CollectionUtil.isNotEmpty(list)) {
            for (OaExamineField field : list) {
                List<ExamineInfoVo> infoVos = examineInfoVos.stream().filter(item -> item.getExamineId().equals(field.getExamineCategoryId())).collect(Collectors.toList());
                Integer oaType = 0;
                if (CollectionUtil.isNotEmpty(infoVos)) {
                    ExamineInfoVo infoVo = CollectionUtil.getFirst(infoVos);
                    oaType = infoVo.getOaType();
                    if (Objects.equals(oaType, 2) && "审批内容".equals(field.getName())) {
                        field.setName("请假事由");
                    }
                }
                //添加语言包key
                Map<String, Object> map = new HashMap<>();
                map.put("fileName", "customField." + "oaExamine" + oaType + "." + field.getFieldName());
                map.put("chinese", field.getName());
                map.put("translateName", "");
                listMap.add(map);
                //添加语言包key
                List<Object> setting = field.getSetting();
                if (CollectionUtil.isNotEmpty(setting)) {

                    Map<String, String> optionsKeyMap = LanguageFieldUtil.getOptionsKeyMap("customField." + "oaExamine" + oaType + ".", field.getFieldName(), setting);

                    for (int i = 0; i < setting.size(); i++) {
                        Object o = setting.get(i);
                        if (ObjectUtil.isNotEmpty(o) && BaseUtil.isJSON(StrUtil.toString(o))) {
                            Object name = "";
                            Object object = JSON.parse(StrUtil.toString(o));
                            if (object instanceof JSONObject) {
                                JSONObject jsonObject = (JSONObject) object;
                                name = jsonObject.get("name");
                            } else if (object instanceof JSONArray) {
                                JSONArray jsonArray = (JSONArray) object;
                                name = jsonArray.get(0);
                            } else {
                                name = object;
                            }
                            map.put("fileName", optionsKeyMap.get(StrUtil.toString(i)));
                            map.put("chinese", name);
                            map.put("translateName", "");
                            listMap.add(map);
                        }
                    }
                }

            }
        }

        //日志模板
        List<OaLogTemplateConfig> configs = oaLogTemplateConfigService.list();
        if (CollectionUtil.isNotEmpty(configs)) {
            for (OaLogTemplateConfig config : configs) {
                Map<String, Object> map = new HashMap<>();
                map.put("fileName", "oa.log.template.config." + config.getName());
                map.put("chinese", config.getName());
                map.put("translateName", "");
                listMap.add(map);
            }
        }
        //日志打印模板
        List<OaLogPrintTemplate> printTemplates = oaLogPrintTemplateService.list();
        if (CollectionUtil.isNotEmpty(printTemplates)) {
            for (OaLogPrintTemplate template : printTemplates) {
                Map<String, Object> map = new HashMap<>();
                map.put("fileName", "oa.log.print.template." + template.getTemplateName());
                map.put("chinese", template.getTemplateName());
                map.put("translateName", "");
                listMap.add(map);
            }
        }

        //日志模板自定义字段
        List<OaLogTemplateField> fields = oaLogTemplateFieldService.list();
        OaLogTemplateField createUserName = new OaLogTemplateField();
        createUserName.setFieldName("createUserName");
        createUserName.setName("创建人");
        fields.add(createUserName);
        OaLogTemplateField createTime = new OaLogTemplateField();
        createTime.setFieldName("createTime");
        createTime.setName("创建时间");
        fields.add(createTime);
        OaLogTemplateField updateTime = new OaLogTemplateField();
        updateTime.setFieldName("updateTime");
        updateTime.setName("更新时间");
        fields.add(createUserName);
        fields.add(createTime);
        fields.add(updateTime);
        if (CollectionUtil.isNotEmpty(fields)) {
            for (OaLogTemplateField field : fields) {
                Map<String, Object> map = new HashMap<>();
                map.put("fileName", "oa.log.template.field." + LanguageFieldUtil.getFieldName(field.getFieldName()));
                map.put("chinese", field.getName());
                map.put("translateName", "");
                listMap.add(map);
            }
        }
        //流程打印模板
        PageEntity entity = new PageEntity();
        entity.setPageType(0);
        BasePage<OaExaminePrintTemplate> basePage = oaExaminePrintTemplateService.getBaseMapper().queryList(entity.parse(), null);
        if (CollectionUtil.isNotEmpty(basePage.getList())) {
            for (OaExaminePrintTemplate template : basePage.getList()) {
                Map<String, Object> map = new HashMap<>();
                map.put("fileName", "oa.examine.print.template.name." + LanguageFieldUtil.getFieldName(template.getExamineName()));
                map.put("chinese", template.getExamineName());
                map.put("translateName", "");
                listMap.add(map);
            }
        }
        //错误信息
        for (OaCodeEnum codeEnum : OaCodeEnum.values()) {
            //添加语言包key
            Map<String, Object> map = new HashMap<>();
            map.put("fileName", "error." + codeEnum.getCode());
            map.put("chinese", AdminLanguageUtil.replaceMsg(codeEnum.getMsg()));
            map.put("translateName", "");
            listMap.add(map);
        }
        //审批打印字段信息
        List<OaLogTemplateFieldVO> templateFields = new ArrayList<>();
        templateFields.add(new OaLogTemplateFieldVO("startAddress", "出发城市"));
        templateFields.add(new OaLogTemplateFieldVO("endAddress", "目的城市"));
        templateFields.add(new OaLogTemplateFieldVO("trip", "单程往返"));
        templateFields.add(new OaLogTemplateFieldVO("vehicle", "交通工具"));
        templateFields.add(new OaLogTemplateFieldVO("endTime", "结束时间"));
        templateFields.add(new OaLogTemplateFieldVO("startTime", "开始时间"));
        templateFields.add(new OaLogTemplateFieldVO("duration", "时长（天）"));
        templateFields.add(new OaLogTemplateFieldVO("description", "备注"));
        templateFields.add(new OaLogTemplateFieldVO("startAddress", "出发城市"));
        templateFields.add(new OaLogTemplateFieldVO("endAddress", "目的城市"));
        templateFields.add(new OaLogTemplateFieldVO("startTime", "开始时间"));
        templateFields.add(new OaLogTemplateFieldVO("endTime", "结束时间"));
        templateFields.add(new OaLogTemplateFieldVO("traffic", "交通费"));
        templateFields.add(new OaLogTemplateFieldVO("diet", "餐饮费"));
        templateFields.add(new OaLogTemplateFieldVO("stay", "住宿费"));
        templateFields.add(new OaLogTemplateFieldVO("other", "其他费用"));
        templateFields.add(new OaLogTemplateFieldVO("money", "合计（元）"));
        templateFields.add(new OaLogTemplateFieldVO("description", "费用明细描述"));
        templateFields.add(new OaLogTemplateFieldVO("flowName", "节点名称"));
        templateFields.add(new OaLogTemplateFieldVO("realname", "审批人"));
        templateFields.add(new OaLogTemplateFieldVO("examineStatus", "审批结果"));
        templateFields.add(new OaLogTemplateFieldVO("remark", "审批意见"));
        templateFields.add(new OaLogTemplateFieldVO("examineTime", "审批时间"));
        for (OaLogTemplateFieldVO recordField : templateFields) {
            //添加语言包key
            Map<String, Object> map = new HashMap<>();
            map.put("fileName", "oa.examine.record.field." + recordField.getFieldName());
            map.put("chinese", recordField.getName());
            map.put("translateName", "");
            listMap.add(map);
        }
        return listMap;
    }

    @Override
    public void setOaExamineDraft(JSONObject jsonObject) {
        OaExamine oaExamine = jsonObject.getObject("oaExamine", OaExamine.class);
        JSONArray oaExamineTravelList = jsonObject.getJSONArray("oaExamineTravelList");
        //报销总金额
        if (oaExamine.getMoney() != null && oaExamine.getMoney().doubleValue() <= 0) {
            throw new CrmException(OaCodeEnum.TOTAL_REIMBURSEMENT_ERROR);
        }
        if (oaExamine.getStartTime() != null && oaExamine.getEndTime() != null) {
            if (!oaExamine.getStartTime().isBefore(oaExamine.getEndTime())) {
                throw new CrmException(OaCodeEnum.EXAMINE_END_TIME_IS_EARLIER_THAN_START_TIME);
            }
        }
        if (oaExamineTravelList != null) {
            for (int i = 0; i < oaExamineTravelList.size(); i++) {
                Object json = oaExamineTravelList.get(i);
                OaExamineTravel oaExamineTravel = TypeUtils.castToJavaBean(json, OaExamineTravel.class);
                //费用明细金额
                if (oaExamineTravel.getMoney() != null && oaExamineTravel.getMoney().doubleValue() <= 0) {
                    throw new CrmException(OaCodeEnum.TOTAL_AMOUNT_OF_EXPENSE_DETAILS_ERROR, i);
                }
                if (oaExamineTravel.getStartTime() != null && oaExamineTravel.getEndTime() != null) {
                    if (!oaExamineTravel.getStartTime().isBefore(oaExamineTravel.getEndTime())) {
                        throw new CrmException(OaCodeEnum.TRAVEL_END_TIME_IS_EARLIER_THAN_START_TIME);
                    }
                }
            }
        }
        String batchId = StrUtil.isNotEmpty(oaExamine.getBatchId()) ? oaExamine.getBatchId() : IdUtil.simpleUUID();
        saveField(oaExamine, jsonObject.getJSONArray("field"), batchId);
        oaExamine.setBatchId(batchId);
        //设置草稿状态
        oaExamine.setExamineFlag(ExamineFlagEnum.DRAFT.getType());
        //临时设置审批流的数据
        oaExamine.setExamineFlowDataDraft(jsonObject.getJSONObject("examineFlowData").toJSONString());

        Long examineId = oaExamine.getExamineId();
        if (examineId == null) {
            save(oaExamine);
            examineId = oaExamine.getExamineId();
        } else {
            updateById(oaExamine);
            examineTravelService.lambdaUpdate().eq(OaExamineTravel::getExamineId, examineId).remove();
            deleteOaExamineRelation(examineId);
        }
        String oaExamineR = "oaExamineRelation";
        if (jsonObject.get(oaExamineR) != null) {
            OaExamineRelation oaExamineRelation = jsonObject.getObject("oaExamineRelation", OaExamineRelation.class);
            // 添加审批关系
            addOaExamineRelation(examineId, oaExamineRelation);
            // 反推活动数据
            addActivity(oaExamine, oaExamineRelation);
        }

        if (oaExamineTravelList != null) {
            for (Object json : oaExamineTravelList) {
                OaExamineTravel oaExamineTravel = TypeUtils.castToJavaBean(json, OaExamineTravel.class);
                oaExamineTravel.setTravelId(null);
                oaExamineTravel.setExamineId(examineId);
                examineTravelService.save(oaExamineTravel);
            }
        }
    }

    /**
     * 功能描述: <br>
     * 〈根据审批状态设置OA流程状态〉
     *
     * @param:
     * @return: void
     * @throws:
     * @author: zyh
     * @date: 2022/12/26 17:03
     */
    private void setExamineFlag(OaExamine oaExamine, Integer examineStatus) {
        switch (examineStatus) {
            case 1:
                oaExamine.setExamineFlag(ExamineFlagEnum.END.getType());
                break;
            case 2:
                oaExamine.setExamineFlag(ExamineFlagEnum.END.getType());
                break;
            case 4:
                oaExamine.setExamineFlag(ExamineFlagEnum.END.getType());
                break;
            case 8:
                oaExamine.setExamineFlag(ExamineFlagEnum.VOID.getType());
                break;
            case 13:
                oaExamine.setExamineFlag(ExamineFlagEnum.END.getType());
                break;
            case 14:
                oaExamine.setExamineFlag(ExamineFlagEnum.END.getType());
                break;
            default:
                oaExamine.setExamineFlag(ExamineFlagEnum.NORMAL.getType());
                break;
        }
    }

    @Override
    public Map<Integer, Set<Long>> getRelation(Long oaExamineId) {
        Map<Integer, Set<Long>> relationIdsMap = examineRelationService.lambdaQuery()
                .select(OaExamineRelation::getRelationId, OaExamineRelation::getType)
                .eq(OaExamineRelation::getExamineId, oaExamineId)
                .list()
                .stream()
                .collect(Collectors.groupingBy(OaExamineRelation::getType, Collectors.mapping(OaExamineRelation::getRelationId, Collectors.toSet())));


        return relationIdsMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFieldInfo(ExamineUpdateFieldBO data) {
        if (data.getData().size() == 0) {
            return;
        }

        List<JSONObject> list = data.getData().stream().sorted(Comparator.comparing(e -> e.getDate("createTime"))).collect(Collectors.toList());
        Object batchId = list.get(0).get("batchId");
        JSONObject entityObject = new JSONObject();
        entityObject.put("examineId", data.getTypeId());
        entityObject.put("batchId", batchId);

        JSONArray array = new JSONArray();
        List<OaExamineTravel> examineTravels = new ArrayList<>();
        for (JSONObject record : list) {
            String fieldType = "fieldType";
            if (record.getInteger(fieldType) == 1) {
                Integer type = record.getInteger("type");
                //todo 这里需要特殊处理
                if (FieldEnum.BUSINESS_CAUSE.getType().equals(type) || FieldEnum.EXAMINE_CAUSE.getType().equals(type)) {
                    if (ObjectUtil.isNotEmpty(record.get("newValue"))) {
                        List<OaExamineTravel> travelList = examineTravelService.lambdaQuery().eq(OaExamineTravel::getExamineId, data.getTypeId()).list();

                        JSONArray objects = JSON.parseArray(record.get("newValue").toString());
                        for (int i = 0; i < objects.size(); i++) {
                            JSONObject object = objects.getJSONObject(i);
                            if (StrUtil.isEmpty(object.getString("travelId"))) {
                                object.put("examineId", data.getTypeId());
                                object.put("createUserId", record.get("createUserId"));
                                examineTravels.add(object.toJavaObject(OaExamineTravel.class));
                                continue;
                            }
                            for (OaExamineTravel oaExamineTravel : travelList) {
                                if (oaExamineTravel.getTravelId().equals(object.getLong("travelId"))) {
                                    examineTravels.add(BeanUtil.fillBeanWithMap(object, oaExamineTravel, true));
                                }
                            }
                        }
                    }
                    examineTravelService.lambdaUpdate().eq(OaExamineTravel::getExamineId, data.getTypeId()).remove();

                } else {
                    entityObject.put(StrUtil.toUnderlineCase(record.getString("fieldName")), record.get("newValue"));
                }
            } else if (record.getInteger(fieldType) == 0 || record.getInteger(fieldType) == 2) {

                Integer type = record.getInteger("type");
                JSONObject filedVO = new JSONObject();
                filedVO.put("fieldId", record.getLong("fieldId"));
                filedVO.put("fieldName", record.getString("fieldName"));
                filedVO.put("fieldType", record.getInteger(fieldType));
                filedVO.put("name", record.getString("name"));
                filedVO.put("type", record.getInteger("type"));
                filedVO.put("value", record.getString("newValue"));

                if (FieldEnum.DETAIL_TABLE.getType().equals(type)) {
                    List<OaExamineFieldExtend> extendList = oaExamineFieldExtendService.queryOaExamineFieldExtend(record.getLong("fieldId"));

                    //初始行数据
                    List<Map<String, Object>> initRow = new ArrayList<>();
                    if (ObjectUtil.isNotEmpty(extendList)) {
                        for (OaExamineFieldExtend oaFieldExtend : extendList) {
                            Map<String, Object> map = BeanUtil.beanToMap(oaFieldExtend);
                            map.put("value", "");
                            initRow.add(map);
                        }
                    }
                    String oldValue = "";

                    OaExamineData examineData = examineDataService.lambdaQuery()
                            .select(OaExamineData::getValue, OaExamineData::getId)
                            .eq(OaExamineData::getFieldId, record.getLong("fieldId"))
                            .eq(OaExamineData::getBatchId, batchId).one();

                    if (ObjectUtil.isNotEmpty(examineData)) {
                        oldValue = examineData.getValue();
                    }
                    Object value = ExamineUpdateUtils.disposeTable(record.get("newValue"), initRow, oldValue);
                    filedVO.put("value", value);
                }
                array.add(filedVO);
            }
        }

        OaExamine oaExamine = BeanUtil.copyProperties(entityObject, OaExamine.class);
        updateById(oaExamine);
        saveField(oaExamine, array, entityObject.getString("batchId"), true);

        examineTravelService.saveBatch(examineTravels);

    }


    @Override
    public List<Map<String, Object>> queryExamineUpdateLog(List<ExamineFlowFieldUpdateLogBO> list) {

        Map<Tuple, List<ExamineFlowFieldUpdateLogBO>> collect = list.stream().collect(Collectors.groupingBy(e -> new Tuple(e.getCreateTime(), e.getCreateUserId())));

        TreeMap<Tuple, List<ExamineFlowFieldUpdateLogBO>> tupleListTreeMap = new TreeMap<>(Comparator.comparing(e -> e.get(0)));

        tupleListTreeMap.putAll(collect);

        List<Map<String, Object>> data = new ArrayList<>();

        for (Tuple objects : tupleListTreeMap.keySet()) {
            List<ExamineFlowFieldUpdateLogBO> fieldUpdateLogBOS = tupleListTreeMap.get(objects);
            List<String> textList = new ArrayList<>();
            List<String> transList = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            for (ExamineFlowFieldUpdateLogBO log : fieldUpdateLogBOS) {
                if (fieldUpdateLogBOS.indexOf(log) == 0) {
                    map.put("realname", UserCacheUtil.getUserName(log.getCreateUserId()));
                    map.put("createTime", log.getCreateTime());
                }
                if (log.getFieldType() == 0) {
                    if (Objects.equals(FieldEnum.parse(log.getType()), FieldEnum.DETAIL_TABLE)) {
                        ActionRecordUtil.parseDetailTable(log.getOldValue(), log.getNewValue(), log.getName(), log.getType(), textList);
                    } else {
                        String oldFieldValue = (String) ActionRecordUtil.parseValue(log.getOldValue(), log.getType(), false);
                        String newFieldValue = (String) ActionRecordUtil.parseValue(log.getNewValue(), log.getType(), false);

                        String transOldFieldValue = (String) ActionRecordUtil.transParseValue(oldFieldValue);
                        String transNewFieldValue = (String) ActionRecordUtil.transParseValue(newFieldValue);
                        if (!oldFieldValue.equals(newFieldValue)) {
                            if (StrUtil.isEmpty(oldFieldValue)) {
                                oldFieldValue = "空";
                            }
                            if (StrUtil.isEmpty(newFieldValue)) {
                                newFieldValue = "空";
                            }

                            String formatKey = ActionRecordUtil.formatKey(OaEnum.parse(log.getLabel()), log.getFieldName());
                            textList.add("将" + log.getName() + " 由" + oldFieldValue + "修改为" + newFieldValue + "。");
                            transList.add(" " + formatKey + " " + transOldFieldValue + LanguageFieldEnum.ACTIONRECORD_UPDATE.getFieldFormat() + transNewFieldValue + "。");
                        }
                    }
                } else {
                    if (Objects.equals(FieldEnum.parse(log.getType()), FieldEnum.EXAMINE_CAUSE) || Objects.equals(FieldEnum.parse(log.getType()), FieldEnum.BUSINESS_CAUSE)) {
                        ActionRecordUtil.parseCause(log.getOldValue(), log.getNewValue(), log.getName(), log.getType(), textList);
                    } else {
                        ActionRecordUtil.getRecord(textList, transList, log);
                    }
                }
            }

            map.put("content", textList);
            map.put("transContent", transList);
            data.add(map);
        }

        return data;
    }

    @Override
    public void updateExamineRelId(Integer type, Long oldId, Long newId) {
        boolean exists = examineRelationService.lambdaQuery().eq(OaExamineRelation::getType, type).eq(OaExamineRelation::getRelationId, oldId).exists();
        if(exists){
            examineRelationService.lambdaUpdate().set(OaExamineRelation::getRelationId, newId).eq(OaExamineRelation::getType, type).eq(OaExamineRelation::getRelationId, oldId).update();
        }
    }

    /**
     * 通过fieldId查询出审批ID
     *
     * @param fieldId
     * @return
     */
    @Override
    public List<String> queryLeaveTypeList(Long fieldId) {
        OaExamineField oaExamineField = examineFieldService.getById(fieldId);
        List<String> leaveTypeList = new ArrayList<>();
        if (ObjectUtil.isNotNull(oaExamineField) && StrUtil.isNotBlank(oaExamineField.getOptions())) {
            String[] split = oaExamineField.getOptions().split(",");
            for (String leaveType : split) {
                leaveTypeList.add(leaveType);
            }
        }
        return leaveTypeList;
    }
}
